package a1;

import java.awt.Color;
import java.awt.GridLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import javax.swing.colorchooser.AbstractColorChooserPanel;

public class RGBSliderChooserPanel extends AbstractColorChooserPanel implements PropertyChangeListener {
	
	//private Dimension jLabelSize;	// holds the preferred size for all JLabels
	
	private JPanel leftPanel;	// holds the contents in the left side of this component
	private JPanel rightPanel;	// holds the contents in the right side of this component
	
	// Panels for all three colors, go in leftPanel
	private TitledSpinnerSliderPanel greenPanel;
	private TitledSpinnerSliderPanel redPanel;
	private TitledSpinnerSliderPanel bluePanel;
	
	// Panel that previews the currently selected color, goes in rightPanel
	private JPanel previewPanel;
	private JPanel previewPanelGrayscale;

	private int grayscaleMode;

	//private Model ModelObj; 
	// TODO: use a static method to convert to grayscale 
	// (it should be static because we don't pass this panel a Model object, 
	// and creating one here would be a different object than the one we are 
	// working on in View
	
	private Color color;
	

	/**
	 * 
	 */
	private static final long serialVersionUID = 1112806278632903159L;

	@Override
	protected void buildChooser() {
		// TODO Auto-generated method stub
		//this.setLayout(new GridLayout(3, 0));
		
		//TODO: let user choose this
		grayscaleMode = 3;

		this.leftPanel = new JPanel();
		// set the GridLayout to have as many rows as the  number of colors we can select from
		// no columns necessary as we want everything to be displayed vertically
		this.leftPanel.setLayout(new GridLayout(Constants.NUM_COLORS, 0));
		
		this.rightPanel = new JPanel();

		this.rightPanel.setLayout(new GridLayout(Constants.NUM_COLORS_DISPLAYED, 0));


		// Set a border for the panel that will contain the colour preview
		this.rightPanel.setBorder(new TitledBorder(
				BorderFactory.createEtchedBorder(), 
				Constants.PREVIEW_TEXT)
				);
		
		this.greenPanel = new TitledSpinnerSliderPanel(Constants.GREEN_TEXT);
		this.bluePanel = new TitledSpinnerSliderPanel(Constants.BLUE_TEXT);
		this.redPanel= new TitledSpinnerSliderPanel(Constants.RED_TEXT);
		
		// Add listeners which will update the preview panel whenever the sliders/spinners are moved
		this.redPanel.addPropertyChangeListener(Constants.COLOR_UPDATE_EVENT, this);
		this.greenPanel.addPropertyChangeListener(Constants.COLOR_UPDATE_EVENT, this);
		this.bluePanel.addPropertyChangeListener(Constants.COLOR_UPDATE_EVENT, this);
		
		previewPanel = new JPanel();
		previewPanelGrayscale = new JPanel();
		// this might be changed later so we can set the background dynamically via a controller
		previewPanel.setBackground(Color.black);	
		previewPanel.setPreferredSize(Constants.PREVIEW_PREFFERED_SIZE);
		previewPanelGrayscale.setBackground(Color.black);	
		previewPanelGrayscale.setPreferredSize(Constants.PREVIEW_PREFFERED_SIZE);
		// this is a constant size we believe the user will find enjoyable
		
		// Add all panels to their parent panels and add to the content pane
		
		this.leftPanel.add(this.redPanel);
		this.leftPanel.add(this.greenPanel);
		this.leftPanel.add(this.bluePanel);
		
		this.rightPanel.add(this.previewPanel);
		this.rightPanel.add(this.previewPanelGrayscale);
		
		this.add(this.leftPanel);
		this.add(this.rightPanel);
	}

	@Override
	public String getDisplayName() {
		// TODO Auto-generated method stub
		return Constants.RGB_SLIDER_TEXT;
	}

	@Override
	public Icon getLargeDisplayIcon() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Icon getSmallDisplayIcon() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void updateChooser() {
		// TODO Auto-generated method stub
		try
		{	
			// catche all current colors
			int red = this.color.getRed();
			int green = this.color.getGreen();
			int blue = this.color.getBlue();
			
			// set panels to current color values
			this.redPanel.setValue(red);
			this.greenPanel.setValue(green);
			this.bluePanel.setValue(blue);
		}
		catch (Exception e)
		{
			System.out.println("Null pointer Exception " + e.getMessage());
			//set it to 0,0,0 if the color can't be reached.
			this.redPanel.setValue(0);
			this.greenPanel.setValue(0);
			this.bluePanel.setValue(0);
		}
		
		//start preview color as black? seems appropriate
		//this.previewPanel.setBackground(this.color);
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		// TODO Auto-generated method stub
		this.color = new Color (this.redPanel.getValue(),	// grab the red value
								this.greenPanel.getValue(), // grab the green value
								this.bluePanel.getValue()	// grab the blue value
								);
		

		this.updatePreview();

		// fire off another property change so the text field in the view is updated with the new color
		firePropertyChange(Constants.TEXT_UPDATE_EVENT, false, true);
	}
	
	public void setColor(Color c) {
		this.color = c;
		//System.out.println("RGBSliderChooserPanel.setColor() color: " + c.toString());
		this.updateChooser();
	}
	
	public Color getColor() {
		return new Color (this.redPanel.getValue(),	// grab the red value
				this.greenPanel.getValue(),			// grab the green value
				this.bluePanel.getValue()			// grab the blue value
				);
	}
	/**
	 * Updates the preview panel for this RGBSliderChooserPanel
	 */
	private void updatePreview()
	{
		// set the previewPanel to display the user's selected color and grayscale color
		this.previewPanel.setBackground(this.color);
		this.previewPanelGrayscale.setBackground(Model.toGrayscale(this.color, this.grayscaleMode));
	}
}
